package org.baygo.view.fxview;

import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.FileChooser;
import javafx.util.Pair;
import org.babygo.net.NettyProxy;
import org.babygo.net.Worker;
import org.babygo.file.handler.FileMsgHandler;
import org.babygo.net.file.FileObj;

import java.io.File;
import java.io.IOException;
import java.util.Optional;

public class MainController {

    public Label serverStatus;
    public MenuItem server;
    public MenuItem client;
    public VBox connectListBox;

    public void serverEvent(ActionEvent actionEvent) throws IOException {
        String serverCommand = server.getText();
        if (serverCommand.equals("启动服务")) {
            startServer();
        } else {
            closeServer();
        }
    }

    private void startServer() {
        serverStatus.setText("服务已启动!");
        serverStatus.setBackground(new Background(new BackgroundFill(Color.GREEN, null, null)));
        Proxy proxy = NettyProxy.get();
        proxy.workHandler(new Worker(new FileMsgHandler(new FxFileChooseHandler()), null));
        proxy.startNewServer(8000);
        server.setText("关闭服务");
    }

    private void closeServer() {
        serverStatus.setText("服务已关闭!");
        serverStatus.setBackground(new Background(new BackgroundFill(null, null, null)));
        NettyProxy.get().closeServer();
        server.setText("启动服务");
    }

    public void clientEvent(ActionEvent actionEvent) {
        String clientCommand = client.getText();
        openDialog();
    }

    private void openDialog() {
        Dialog<Pair<String, String>> dialog = new Dialog<>();

        // Set the button types.
        ButtonType confirmButtonType = new ButtonType("确定", ButtonBar.ButtonData.OK_DONE);
        dialog.getDialogPane().getButtonTypes().addAll(confirmButtonType, ButtonType.CANCEL);

        // Create the username and password labels and fields.
        GridPane grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(20, 150, 10, 10));

        TextField ipText = new TextField();
        ipText.setPromptText("IP");
        TextField portText = new TextField();
        portText.setPromptText("Port");

        grid.add(new Label("IP:"), 0, 0);
        grid.add(ipText, 1, 0);
        grid.add(new Label("Port:"), 0, 1);
        grid.add(portText, 1, 1);

        // Enable/Disable login button depending on whether a username was entered.
        Node confirmButton = dialog.getDialogPane().lookupButton(confirmButtonType);
        confirmButton.setDisable(true);

        // Do some validation (using the Java 8 lambda syntax).
        ipText.textProperty().addListener((observable, oldValue, newValue) -> {
            confirmButton.setDisable(newValue.trim().isEmpty());
        });

        dialog.getDialogPane().setContent(grid);

        // Request focus on the username field by default.
        Platform.runLater(() -> ipText.requestFocus());

        // Convert the result to a username-password-pair when the login button is clicked.
        dialog.setResultConverter(dialogButton -> {
            if (dialogButton == confirmButtonType) {
                return new Pair<>(ipText.getText(), portText.getText());
            }
            return null;
        });

        Optional<Pair<String, String>> result = dialog.showAndWait();

        result.ifPresent(ipAndPort -> {
            System.out.println("ip=" + ipAndPort.getKey() + ", port=" + ipAndPort.getValue());
            addNewConnector(ipAndPort.getKey(), Integer.valueOf(ipAndPort.getValue()));
        });
    }

    private void addNewConnector(String ip, int port) {
        Label newChannel = new Label(ip + ":" + port);
        newChannel.setMinSize(150, 25);
        newChannel.setBackground(new Background(new BackgroundFill(Color.GREEN, null, null)));
        Button confirmButton = new Button("连接");
        addConfirmButtonEvent(confirmButton, ip, port);
        Button sendButton = new Button("发送");
        HBox hBox = new HBox();
        hBox.setStyle("-fx-border-style: solid inside;-fx-border-color:  #473d3d89;-fx-min-width: 300");
        hBox.getChildren().addAll(newChannel, confirmButton, sendButton);
        connectListBox.getChildren().add(hBox);
    }

    public void addConfirmButtonEvent(Button confirmButton, String ip, int port) {
        System.out.println("连接远程端口");
        confirmButton.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent event) {
                Proxy proxy = NettyProxy.get();
                proxy.workHandler(new Worker(new FileMsgHandler(new FxFileChooseHandler()), null));
                String channelId = proxy.connectRemote(ip, port);
//                newChannel.setText(channelId);
            }
        });
    }

    public void addSendButtonEvent(String channelId, Button sendButton, String ip, int port) {
        System.out.println("发送文件给远端!");
        sendButton.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent event) {
                FileChooser fileChooser = new FileChooser();
                fileChooser.setTitle("Save File");
                File file = fileChooser.showOpenDialog(BabyGoApplication.mainStage);
                try {
                    FileObj fileObj = new FileObj(file);
                    while (true) {
                        if (!fileObj.readable()) {
                            NettyProxy.get().getChannel(channelId).write(fileObj.read());
                        } else {
                            break;
                        }
                    }
                } catch (IOException e) {
                    System.out.println(e.getMessage());
                }

            }
        });
    }
}